/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package observertest;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import java.lang.Object;
import java.util.Arrays;
import java.util.Arrays.*;
import java.util.Random;

/**
 *
 * @author Student
 */
public class Tile extends JButton implements TileObserver, ActionListener {
    
    
    //<editor-fold desc="fields">
    //private ImageOperations imageOps = new ImageOperations();
    private ImageIcon rockIcon, critterIcon, bugIcon, flowerIcon;
    private boolean rock, critter, flower, bug, invalid;
    private int index; 
    private ArrayList listeners = new ArrayList();
    private ArrayList<Actor> occupants = new ArrayList();
    private Object[] neighbors = new Object[8];
    private Random generator = new Random();
    //private ArrayList<Object> neighbors = new ArrayList<Object> (10);
    //private List tempneighbors [null, null, null, null, null, null, null, null];
    //</editor-fold>
    
    //<editor-fold defaultstate="collapsed" desc="get set methods">
    public int getIndex() {
        return index;
    }
    
    public void setIndex(int index) {
        this.index = index;
    }
    
    public boolean isBug() {
        return bug;
    }

    public void setBug(boolean bug) {
        this.bug = bug;
        updateState();
    }

    public boolean isCritter() {
        return critter;
    }

    public void setCritter(boolean critter) {
        this.critter = critter;
        updateState();
    }

    public boolean isFlower() {
        return flower;
    }

    public void setFlower(boolean flower) {
        this.flower = flower;
        updateState();
    }

    public boolean isInvalid() {
        return invalid;
    }

    public void setInvalid(boolean invalid) {
        this.invalid = invalid;
        updateState();
    }

    public boolean isRock() {
        return rock;
    }

    public void setRock(boolean rock) {
        this.rock = rock;
        updateState();
    }
    //</editor-fold>
    
    public Tile(int index, int pixels, ImageIcon rock, ImageIcon critter, ImageIcon bug, ImageIcon flower){
        this.index  = index;
        //this.pixels = pixels;
        this.addActionListener(this);
        
        //Integer.parseInt(index);
        this.setText(Integer.toString(this.index));
        //neighbors.ensureCapacity(8);

        
        rockIcon = rock;
        flowerIcon = flower;
        bugIcon = bug;
        critterIcon = critter;
    }

    
    //<editor-fold defaultstate="collapsed" desc="Interface Override methods">
    @Override
    public void actionPerformed( ActionEvent e){
        System.out.println("tile " + index + " clicked");
        //notifyListeners(new TileEvent(index, neighbors));
        notifyListeners(new TileEvent(this));
        
    }
    
    @Override
    public void addListener( GameListener listener) {
        listeners.add(listener);
    }
    
    @Override
    public void removeListener( GameListener listener) {
        listeners.remove(listener);
    }
    
    @Override
    public void notifyListeners(TileEvent e){
        Iterator i = listeners.iterator();
        while (i.hasNext()) {
            GameListener o = (GameListener) i.next();
            //o.update( new TileEvent( index , neighbors));
            o.update(e);
        }
    }
    //</editor-fold>
    
    
    
    public void generateNieghbors( int rows, int cols){
        
        //neighbors = new ArrayList<Object>((int)8);
        //neighbors.ensureCapacity(8);
        System.out.println("generateNeighbors called\tnieghbors[].length = " + neighbors.length);
        for (Object o : neighbors){
            o = null;
        }
        
        //not using  int[] any more
        if (index > cols) {
            neighbors[1] = (Integer)(index - cols);
            //neighbors.add(1, index - cols);
        }
        if (index < cols*(rows-1)){
            neighbors[6] = (Integer)(index + cols);
            //neighbors.add(6, index + cols);

        }
        if ((index % cols)!=0){
            neighbors[3] = (Integer)(index - 1);
            //neighbors.add(3, index - 1);
        }
        if ((index%cols)!=(cols-1)){
            neighbors[4] = (Integer)(index + 1);
            //neighbors.add(4, index + 1);
        }
       
        if ((neighbors[1]!=null)&&(neighbors[3]!=null)){
            
            neighbors[0] =  (Integer)((index - cols) - 1);
            //neighbors.add(0, (index - cols)-1);
        }
        if ((neighbors[1]!=null)&&(neighbors[4]!=null)){
            neighbors[2] =  (Integer)((index - cols) + 1);
            //neighbors.add(2, (index - cols)+1);
        }
        if ((neighbors[6]!=null)&&(neighbors[3]!=null)){
            neighbors[5] =  (Integer)((index + cols) - 1);
            //neighbors.add(5, (index - cols)-1);
        }
        if ((neighbors[6]!=null)&&(neighbors[4]!=null)){
            neighbors[7] =  (Integer)((index + cols) + 1);
            //neighbors.add(5, (index - cols)+1);
        }
        
        //Neighbors = new Arrays.asList(neighbors);
        //Neighbors = new ArrayList(neighbors);
    }
    
    private void updateState(){
        if (this.rock == true){
            this.setIcon(rockIcon);
        }else if (this.critter == true){
            this.setIcon(critterIcon);
        }else if (this.bug == true){
            this.setIcon(bugIcon);
        }else if (this.flower == true){
            this.setIcon(flowerIcon);
        }else{
            this.setIcon(null);
        }
    }
    
    public Integer pickRandomNeighbor(){
        int testNeighbor;
        int tries = 0;
        do {
            testNeighbor  = generator.nextInt(8);
            if( neighbors[testNeighbor] != null){
                return (Integer)neighbors[testNeighbor];
            }
        } while ( tries < 16);
        return null;
    }

    public void addOccupant( Actor occupant){
        occupants.add(occupant);
        updateIcon();
    }
    
    public void removeOccupant( Actor occupant){
        occupants.remove(occupant);
    }
    
    private void updateIcon(){
        for (Actor a: occupants){
            if (a instanceof Rock){
                this.setIcon(rockIcon);
            }
            
        }
    }

}
